﻿using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using CodeCamp.Models.Presenters;
using System.Linq;
using CodeCamp.Entities01;

namespace CodeCamp.Controllers
{
  public class PresentersController : Controller
  {
    #region List actions

    // GET: /Presenters/List

    public ActionResult List( string eventName )
    {
      int eventId = EventsHelper.GetEventId( eventName );
      var repository = new CodeCampDataRepository();
      var eventDisplayName = repository.GetEvent( eventId ).DisplayName;
      var eventPresenters = 
        repository.GetPresenters( eventId )
        .Where( p => p.SessionPresenters.Count > 0 )
        .OrderBy( p => p.LastName )
        .ThenBy( p => p.FirstName );

      var userPresenterId = repository.GetPresenter( eventId, User.Identity.Name );

      var presenters = new List<PresentersListViewModel.Presenter>();
      foreach ( var presenter in eventPresenters )
      {
        var sessions = new List<PresentersListViewModel.Presenter.Session>();
        foreach ( var sessionPresenter in presenter.SessionPresenters )
        {
          var session = sessionPresenter.Session;
          sessions.Add(
            new PresentersListViewModel.Presenter.Session
            {
              SessionId = session.Id,
              Title = session.Title
            } );
        }

        presenters.Add(
          new PresentersListViewModel.Presenter
          {
            PresenterId = presenter.Id,
            Name = string.Format( "{0} {1}", presenter.FirstName, presenter.LastName ),
            TwitterName = presenter.TwitterName,
            Biography = presenter.Biography,
            BlogUrl = presenter.BlogUrl,
            WebsiteUrl = presenter.WebsiteUrl,
            Sessions = sessions
          } );
      }

      var model = new PresentersListViewModel
      {
        EventDisplayName = eventDisplayName,
        Presenters = presenters,

        IsUserAuthenticated = User.Identity.IsAuthenticated,
        IsUserAPresenter = userPresenterId != null,
        UserPresenterId = userPresenterId != null
          ? userPresenterId.Id
          : 0
      };

      return View( "List", model );
    }

    #endregion

    #region Details actions

    // GET: /Presenters/Details/5

    public ActionResult Details( int id, string eventName )
    {
      int eventId = EventsHelper.GetEventId( eventName );
      var repository = new CodeCampDataRepository();
      var eventDisplayName = repository.GetEvent( eventId ).DisplayName;
      var presenter = repository.GetPresenter( id );

      var sessions =
        from sessionPresenters in presenter.SessionPresenters
        orderby sessionPresenters.Session.Title
        select new PresentersDetailsViewModel.Session
        {
          SessionId = sessionPresenters.Session.Id,
          Title = sessionPresenters.Session.Title
        };

      var speakerRateSpeaker = repository.GetSpeakerRateSpeaker( presenter.Id );
      var speakerRateSpeakerUrl = speakerRateSpeaker != null ? speakerRateSpeaker.SpeakerUrl : null;

      var model = new PresentersDetailsViewModel
      {
        EventDisplayName = eventDisplayName,
        PresenterId = presenter.Id,
        Name = string.Format( "{0} {1}", presenter.FirstName, presenter.LastName ),
        TwitterName = presenter.TwitterName,
        Biography = presenter.Biography,
        Sessions = sessions.ToList(),
        IsUserAuthorizedToEdit = IsUserAuthorizedToEdit( presenter ),
        BlogUrl = presenter.BlogUrl,
        WebsiteUrl = presenter.WebsiteUrl,
        SpeakerRateSpeakerUrl = speakerRateSpeakerUrl
      };

      return View( "Details", model );
    }
    
    #endregion

    private bool IsUserAuthorizedToEdit( Presenter presenter )
    {
      return presenter.UserIdentityName == User.Identity.Name;
    }

    #region Add actions

    // GET: /Presenters/Add

    [Authorize]
    public ActionResult Add( string eventName )
    {
      int eventId = EventsHelper.GetEventId( eventName );
      var repository = new CodeCampDataRepository();
      var eventDisplayName = repository.GetEvent( eventId ).DisplayName;

      var model = new PresentersAddViewModel
      {
        EventDisplayName = eventDisplayName
      };

      return View( "Add", model );
    }

    // POST: /Presenters/Add

    [AcceptVerbs( HttpVerbs.Post )] 
    [Authorize]
    public ActionResult Add( PresentersAddViewModel model, string eventName )
    {
      try
      {
        int eventId = EventsHelper.GetEventId( eventName );
        var presenter = new Presenter
        {
          UserIdentityName = User.Identity.Name,
          EventId = eventId,
          FirstName = model.FirstName,
          LastName = model.LastName,
          EmailAddress = model.EmailAddress,
          TwitterName = model.TwitterName,
          Biography = model.Biography,
          BlogUrl = model.BlogUrl,
          WebsiteUrl = model.WebsiteUrl,
          ShirtSize = model.ShirtSize
        };
        var repository = new CodeCampDataRepository();
        repository.Add( presenter );
        repository.Save();

        if ( !Roles.IsUserInRole( "Presenter" ) )
          Roles.AddUserToRole( User.Identity.Name, "Presenter" );

        if ( !string.IsNullOrEmpty( model.SpeakerRateSpeakerUrl ) )
        {
          var speakerRateSpeaker = new SpeakerRateSpeaker
            {
              PresenterId = presenter.Id,
              SpeakerUrl = model.SpeakerRateSpeakerUrl
            };
          repository.Add( speakerRateSpeaker );
          repository.Save();
        }

        return RedirectToAction( "List" );
      }
      catch
      {
        return View( "Add", model );
      }
    }

    #endregion

    #region Edit actions

    // GET: /Presenters/Edit/5

    [Authorize]
    public ActionResult Edit( string eventName )
    {
      int eventId = EventsHelper.GetEventId( eventName );
      var repository = new CodeCampDataRepository();
      var eventDisplayName = repository.GetEvent( eventId ).DisplayName;

      var presenter = repository.GetPresenter( eventId, User.Identity.Name );

      // verify that user is authorized to edit this presenter profile
      if ( !IsUserAuthorizedToEdit( presenter ) )
        return View( "PresenterEditAuthorizationError" );

      var speakerRateSpeaker = repository.GetSpeakerRateSpeaker( presenter.Id );

      var model = new PresentersEditViewModel
      {
        EventDisplayName = eventDisplayName,
        PresenterId = presenter.Id,
        FirstName = presenter.FirstName,
        LastName = presenter.LastName,
        TwitterName = presenter.TwitterName,
        EmailAddress = presenter.EmailAddress,
        Biography = presenter.Biography,
        BlogUrl = presenter.BlogUrl,
        WebsiteUrl = presenter.WebsiteUrl,
        ShirtSize = presenter.ShirtSize,
        SpeakerRateSpeakerUrl = speakerRateSpeaker == null ? null : speakerRateSpeaker.SpeakerUrl
      };

      return View( "Edit", model );
    }

    // POST: /Presenters/Edit/5

    [AcceptVerbs( HttpVerbs.Post )]
    [Authorize]
    public ActionResult Edit( PresentersEditViewModel model, string eventName )
    {
      try
      {
        int eventId = EventsHelper.GetEventId( eventName );
        var repository = new CodeCampDataRepository();
        var presenter = repository.GetPresenter( eventId, User.Identity.Name );

        // verify that user is authorized to edit this presenter profile
        if ( !IsUserAuthorizedToEdit( presenter ) )
          return View( "PresenterEditAuthorizationError" );

        presenter.UserIdentityName = User.Identity.Name;
        presenter.FirstName = model.FirstName;
        presenter.LastName = model.LastName;
        presenter.TwitterName = model.TwitterName;
        presenter.EmailAddress = model.EmailAddress;
        presenter.Biography = model.Biography;
        presenter.BlogUrl = model.BlogUrl;
        presenter.WebsiteUrl = model.WebsiteUrl;
        presenter.ShirtSize = model.ShirtSize;

        var speakerRateSpeaker = repository.GetSpeakerRateSpeaker( presenter.Id );
        if ( speakerRateSpeaker != null )
        {
          if ( string.IsNullOrEmpty( model.SpeakerRateSpeakerUrl ) )
            repository.Delete( speakerRateSpeaker );
          else
            speakerRateSpeaker.SpeakerUrl = model.SpeakerRateSpeakerUrl;
        }
        else
        {
          if ( !string.IsNullOrEmpty( model.SpeakerRateSpeakerUrl ) )
            repository.Add( new SpeakerRateSpeaker
              {
                PresenterId = presenter.Id,
                SpeakerUrl = model.SpeakerRateSpeakerUrl
              } );
        }
        repository.Save();

        return RedirectToAction( "List" );
      }
      catch
      {
        return View( "Edit", model );
      }
    }

    #endregion
  }
}
